/**
  ******************************************************************************
  * @file    flash.c
  * @author  GEEKROS,  site:www.geekros.com
  ******************************************************************************
*/

#include "flash.h"

/******************************************************************
  * @ 函数名  ： Flash_Read_Word
  * @ 功能说明： 读取指定地址的半字(16位数据)
  * @ 参数    ： NULL 
  * @ 返回值  ： NULL
  *****************************************************************/
u32 Flash_Read_Word(u32 faddr)
{
	return *(vu32*)faddr;
}

/******************************************************************
  * @ 函数名  ： Flash_Get_Sector
  * @ 功能说明： 获取某个地址所在的flash扇区
  * @ 参数    ： NULL 
  * @ 返回值  ： NULL
  *****************************************************************/
uint16_t Flash_Get_Sector(u32 addr)
{
	if(addr<ADDR_FLASH_SECTOR_1)
	{
		return FLASH_Sector_0;
	}else if(addr<ADDR_FLASH_SECTOR_2){
		return FLASH_Sector_1;
	}else if(addr<ADDR_FLASH_SECTOR_3){
		return FLASH_Sector_2;
	}else if(addr<ADDR_FLASH_SECTOR_4){
		return FLASH_Sector_3;
	}else if(addr<ADDR_FLASH_SECTOR_5){
		return FLASH_Sector_4;
	}else if(addr<ADDR_FLASH_SECTOR_6){
		return FLASH_Sector_5;
	}else if(addr<ADDR_FLASH_SECTOR_7){
		return FLASH_Sector_6;
	}else if(addr<ADDR_FLASH_SECTOR_8){
		return FLASH_Sector_7;
	}else if(addr<ADDR_FLASH_SECTOR_9){
		return FLASH_Sector_8;
	}else if(addr<ADDR_FLASH_SECTOR_10){
		return FLASH_Sector_9;
	}else if(addr<ADDR_FLASH_SECTOR_11){
		return FLASH_Sector_10;
	}else if(addr<ADDR_FLASH_SECTOR_12){
		return FLASH_Sector_11;
	}else if(addr<ADDR_FLASH_SECTOR_13){
		return FLASH_Sector_12;
	}else if(addr<ADDR_FLASH_SECTOR_14){
		return FLASH_Sector_13;
	}else if(addr<ADDR_FLASH_SECTOR_15){
		return FLASH_Sector_14;
	}else if(addr<ADDR_FLASH_SECTOR_16){
		return FLASH_Sector_15;
	}else if(addr<ADDR_FLASH_SECTOR_17){
		return FLASH_Sector_16;
	}else if(addr<ADDR_FLASH_SECTOR_18){
		return FLASH_Sector_17;
	}else if(addr<ADDR_FLASH_SECTOR_19){
		return FLASH_Sector_18;
	}else if(addr<ADDR_FLASH_SECTOR_20){
		return FLASH_Sector_19;
	}else if(addr<ADDR_FLASH_SECTOR_21){
		return FLASH_Sector_20;
	}else if(addr<ADDR_FLASH_SECTOR_22){
		return FLASH_Sector_21;
	}else if(addr<ADDR_FLASH_SECTOR_23){
		return FLASH_Sector_22;
	}
	return FLASH_Sector_23;
}

/******************************************************************
  * @ 函数名  ： Flash_Write
  * @ 功能说明： 写入FLASH数据
  * @ 参数    ： NULL 
  * @ 返回值  ： NULL
  *****************************************************************/
void Flash_Write(u32 Addr, u32 *Buffer, u32 Num)
{
	FLASH_Status status = FLASH_COMPLETE;
	u32 addrx = 0;
	u32 endaddr = 0;
	if(Addr < FLASH_BASE || Addr%4)
	{
		FLASH_Unlock(); //解锁
		FLASH_DataCacheCmd(DISABLE); //FLASH擦除期间，必须禁止数据缓存
		addrx = Addr; //写入起始地址
        endaddr= Addr + Num * 4; //写入结束地址
		if(addrx<0X1FFF0000) //只有主存储区,才需要执行擦除操作
		{
			while(addrx < endaddr) //对非FFFFFFFF的地方,先擦除
			{
				if(Flash_Read_Word(addrx) != 0XFFFFFFFF) //有非0XFFFFFFFF的地方,要擦除这个扇区
				{
					status = FLASH_EraseSector(Flash_Get_Sector(addrx), VoltageRange_3); //VCC=2.7~3.6V之间!!
					if(status!=FLASH_COMPLETE)
					{
						break; //异常
					}
				}else{
					addrx += 4;
				}
			}
		}
		if(status == FLASH_COMPLETE)
		{
			while(Addr < endaddr) //写数据
			{
				if(FLASH_ProgramWord(Addr, *Buffer) != FLASH_COMPLETE) //写入数据
				{
					break; //写入异常
				}
				Addr += 4;
                Buffer++;
			}
		}
	}
	FLASH_DataCacheCmd(ENABLE); //FLASH擦除结束，开启数据缓存
	FLASH_Lock(); //上锁
}

/******************************************************************
  * @ 函数名  ： Flash_Read
  * @ 功能说明： 读取FLASH数据
  * @ 参数    ： NULL 
  * @ 返回值  ： NULL
  *****************************************************************/
void Flash_Read(u32 Addr, u32 *Buffer, u32 Num)
{
	u32 i;
	for(i=0;i<Num;i++)
	{
		Buffer[i] = Flash_Read_Word(Addr); //读取4个字节
		Addr += 4; //偏移4个字节
	}
}
